package com.sise.cn.dao.base;

import com.alibaba.fastjson.JSONObject;
import com.sise.cn.dao.annotation.MybatisLabel;
import com.sise.cn.dao.pagehelper.PageBean;
import lombok.Data;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName BaseMapper
 * @Description
 * @Author CCJ
 * @Date 2020/6/2 21:57
 **/
@Data
public abstract class BaseMapper {

    @Value("${product.db}")
    private String db;

    @Value("${product.soft-delete}")
    private Boolean softDelete;

    protected static final String BASE_MAPPER = "com.sise.cn.dao.base.BaseMapper.";

    private static final String SHOW_COLUMN = "showColumn";

    protected static final String SELECT = "select";

    protected static final String UPDATE = "update";

    protected static final String DELETE = "delete";

    protected static final String INSERT = "insert";

    protected static final String INSERT_UPDATE = "insertUpdate";

    protected static final String SHOW_DATABASES = "showDatabase";

    protected static final String EXECUTOR = "executor";

    protected static final String COUNT = "count";

    protected static final String DB = "__db__";

    protected static final String SOFT_DELETE = "__soft_delete__";

    protected static final String TABLE = "__table__";


    @Autowired
    protected SqlSessionTemplate sqlSessionTemplate;

    public List<String> showColumns(Class<? extends TableSpace> t) {
        Map<String, String> map = new HashMap<>();
        map.put(DB, db);
        map.put(TABLE, mapperName(t));
        List<JSONObject> columns = sqlSessionTemplate.selectList(BASE_MAPPER + SHOW_COLUMN, map);
        return columns.stream().map(e -> e.getString("Field")).collect(Collectors.toList());
    }

    public abstract <T> T select(TableSpace condition, Class<? extends TableSpace> t);

    public abstract <T> List<T> selectList(TableSpace condition, Class<? extends TableSpace> t);

    public abstract <T> PageBean<T> selectByPage(TableSpace condition, Class<? extends TableSpace> t);

    public abstract int update(TableSpace tableSpace);

    public abstract int simpleUpdate(TableSpace tableSpace, Map<String, Object> whereMap);

    public abstract int delete(TableSpace condition);

    public abstract int insert(TableSpace tableSpace);

    public abstract Long insertAndGetId(TableSpace tableSpace);

    public abstract int insertUpdate(TableSpace tableSpace);

    public abstract int batchInsertUpdate(List<TableSpace> list);

    public abstract int batchInsert(List<TableSpace> list);

    public abstract int count(TableSpace condition);

    public boolean existDatabase(String databaseName) {
        List<String> databases = showDatabase(databaseName);
        if (CollectionUtils.isEmpty(databases)) {
            return false;
        }
        return databases.contains(databaseName);
    }

    public abstract List<String> showDatabase(String name);

    public abstract void executor(String sql);


    protected String mapperName(Class<? extends TableSpace> clazz) {
        MybatisLabel mybatisLabel = clazz.getAnnotation(MybatisLabel.class);
        if (mybatisLabel == null || StringUtils.isEmpty(mybatisLabel.mapperName())) {
            String name = clazz.getSimpleName();
            if (name.endsWith("PO")) {
                name = name.substring(0, name.length() - 3);
            }
            return TableSpace.humpToLine(name);
        }
        return mybatisLabel.mapperName();
    }

    protected boolean getSoftDelete() {
        if (softDelete == null) {
            return false;
        }
        return softDelete;
    }
}
